/*
 * ******************************************************************************
 *   Copyright (c) 2014 Gabriele Mariotti.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 *  *****************************************************************************
 */

package it.gmariotti.cardslib.library.cards.material.utils;


import it.gmariotti.cardslib.library.cards.material.MaterialLargeImageCardThumbnail;
import ohos.agp.components.Component;
import ohos.agp.components.element.Element;
import ohos.agp.render.*;
import ohos.agp.utils.*;
import ohos.media.image.PixelMap;

import static ohos.agp.render.Paint.ShaderType.GROUP_SHADER;
import static ohos.agp.render.Paint.ShaderType.PIXELMAP_SHADER;

/**
 * Image with rounded corners
 * <p>
 * You can find the original source here:
 *
 * @author Gabriele Mariotti (gabri.mariotti@gmail.com)
 */
public class RoundCornersDrawable extends Element {

    private static final boolean USE_VIGNETTE = false;

    private final float mCornerRadius;
    private final Rect mRect = new Rect();
    private final Rect mRectBottomR = new Rect();
    private final Rect mRectBottomL = new Rect();
    private final PixelMapShader mBitmapShader;
    private final Paint mPaint;
    private final int mMargin;

    public RoundCornersDrawable(PixelMap bitmap, float cornerRadius, int margin) {
        mCornerRadius = cornerRadius;

        mBitmapShader = new PixelMapShader(new PixelMapHolder(bitmap),
                Shader.TileMode.CLAMP_TILEMODE, Shader.TileMode.CLAMP_TILEMODE);

        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setShader(mBitmapShader, PIXELMAP_SHADER);

        mMargin = margin;
    }

    @Override
    public void setBounds(Rect bounds) {
        super.setBounds(bounds);
        mRect.set(mMargin, mMargin, bounds.getWidth() - mMargin, bounds.getHeight() - mMargin);
        mRectBottomR.set((bounds.getWidth() - mMargin) / 2, (bounds.getHeight() - mMargin) / 2, bounds.getWidth() - mMargin, bounds.getHeight() - mMargin);
        mRectBottomL.set(0, (bounds.getHeight() - mMargin) / 2, (bounds.getWidth() - mMargin) / 2, bounds.getHeight() - mMargin);

        if (USE_VIGNETTE) {
            Point point = new Point(mRect.getCenterX(), mRect.getCenterY() * 1.0f / 0.7f);
            RadialShader vignette = new RadialShader(point, mRect.getCenterX() * 1.3f, new float[]{0.0f, 0.7f, 1.0f},
                    new Color[]{new Color(0), new Color(0), new Color(0x7f000000)}, Shader.TileMode.CLAMP_TILEMODE);

            Matrix oval = new Matrix();
            oval.setScale(1.0f, 0.7f);
            vignette.setShaderMatrix(oval);

            mPaint.setShader(
                    new GroupShader(mBitmapShader, vignette, BlendMode.SRC_OVER), GROUP_SHADER);
        }
    }


    @Override
    public void drawToCanvas(Canvas canvas) {
        super.drawToCanvas(canvas);
        canvas.drawRoundRect(new RectFloat(mRect), mCornerRadius, mCornerRadius, mPaint);
        canvas.drawRect(new RectFloat(mRectBottomR), mPaint);
        canvas.drawRect(new RectFloat(mRectBottomL), mPaint);
    }

    //todo
//    @Override
//    public int getOpacity() {
//        return PixelFormat.TRANSLUCENT;
//    }

    @Override
    public void setAlpha(int alpha) {
        mPaint.setAlpha(alpha);
    }

//todo
//    @Override
//    public void setColorFilter(ColorFilter cf) {
//
//    }

    @Override
    public void setColorMatrix(ColorMatrix matrix) {
        super.setColorMatrix(matrix);
        mPaint.setColorMatrix(matrix);
    }

    /**
     * This method applies a top rounded corners to the bitmap for
     * and attaches the bitmap to the view.
     *
     * @param thumbnail @link{MaterialLargeImageCardThumbnail}
     * @param imageView the view
     * @param bitmap    the bitmap
     * @return boolean
     */
    public static boolean applyRoundedCorners(MaterialLargeImageCardThumbnail thumbnail, Component imageView, PixelMap bitmap) {

        if (thumbnail != null && thumbnail.getParentCard() != null
                && thumbnail.getParentCard().getCardView() != null) {
            RoundCornersDrawable round = new RoundCornersDrawable(bitmap, 0, 0);
            imageView.setBackground(round);
            return true;
        }
        return false;
    }
}